package com.guoxin.part4.chapter15;

/**
 * 观察者线程
 * 
 * @author guoxin
 * @date 2019/8/30
 */
public final class ObservableThread<T> extends Thread implements Observable {
	/**
	 * 任务生命周期接口
	 */
	private final TaskLifeCycle<T> lifeCycle;

	private final Task<T> task;
	
	/**
	 * 任务声明周期
	 */
	private Cycle cycle;

	@Override
	public Cycle getCycle() {
		return this.cycle;
	}

	public ObservableThread(Task<T> task) {
		this(new TaskLifeCycle.EmptyLifeCycle<>(), task);
	}

	public ObservableThread(TaskLifeCycle<T> lifeCycle, Task<T> task) {
		if (task == null) {
			throw new IllegalArgumentException("The task is required.");
		}
		this.lifeCycle = lifeCycle;
		this.task = task;
	}

	@Override
	public final void run() {
		this.update(Cycle.STARTED, null, null);
		try {
			this.update(Cycle.RUNNING, null, null);
			T result = this.task.call();
			this.update(Cycle.DONE, result, null);
		} catch (Exception e) {
			this.update(Cycle.DONE, null, e);
		}
	}

	private void update(Cycle cycle, T result, Exception e) {
		this.cycle = cycle;
		if (lifeCycle == null) {
			return;
		}
		try {
			switch (cycle) {
			case STARTED:
				this.lifeCycle.onStart(Thread.currentThread());
				break;
			case RUNNING:
				this.lifeCycle.onRunning(Thread.currentThread());
				break;
			case DONE:
				this.lifeCycle.onFinish(Thread.currentThread(), result);
				break;
			case ERROR:
				this.lifeCycle.onError(Thread.currentThread(), e);
			default:
			}
		} catch (Exception ex) {
			if (cycle == Cycle.ERROR) {
				throw ex;
			}
		}
	}

}
